import React, {useEffect, useState} from "react";

export function HookTest2() {
    const [count, setCount] = useState(0);

    /**
     * useEffect 作用：
     *     1. useEffect 会在每次渲染后都执行，不用再去考虑“挂载”还是“更新”。
     *     2. useEffect 调度的 effect 不会阻塞浏览器更新屏幕，这让你的应用看起来响应更快。
     *
     * 无需清除的 effect ：
     *     1. 我们只想在 React 更新 DOM 之后运行一些额外的代码。比如发送网络请求，手动变更 DOM，记录日志，这些都是常见的无需清除的操作。
     * 需要清除的 effect ：
     *     1. 一些副作用是需要清除的。例如订阅外部数据源、定时器等。清除工作是非常重要的，可以防止引起内存泄露！
     *     2. 如果你的 effect 返回一个函数，React 将会在执行清除操作时调用它。
     *     3. 使用多个 Effect 实现关注点分离，React 将按照 effect 声明的顺序依次调用组件中的每一个 effect。
     *     4. Effect 会在调用一个新的 effect 之前对前一个 effect 进行清理。
     *
     * 性能优化：
     *     1. 你可以通知 React 跳过对 effect 的调用，只要传递数组作为 useEffect 的第二个可选参数即可。
     *     2. 如下代码，如果 count 第二次渲染时的值没有改变，那么 react 会跳过此次 effect。
     *     3. 如果传入的数组为空数组 []，那么 effect 只会在组件挂载和卸载时执行执行一次。
     *
     * 规则：
     *     1. 只在 React 函数和自定义 Hook 中调用 Hook
     *     2. 不要在循环，条件或嵌套函数中调用 Hook。
     *
     * 跳过 state 更新
     *     1. useCount 传入 count 时，React 将跳过子组件的渲染及 effect 的执行。
     *     2. 可测试下面的 Click me 1 按钮
     */
    useEffect(() => {
        document.title = `You clicked ${count} times`;
    }, [count]); // 仅在 count 更改时更新

    useEffect(() => {
        alert(`传入数组为空，只会在组件挂载和卸载时执行执行一次。`);
    }, []);

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>
                Click me
            </button>
            <button onClick={() => setCount(count)}>
                Click me 1
            </button>
        </div>
    );
}
